<?php
// +----------------------------------------------------------------------
// | [KyPHP System] Copyright (c) 2020 http://www.kuryun.com/
// +----------------------------------------------------------------------
// | [KyPHP] 并不是自由软件,你可免费使用,未经许可不能去掉KyPHP相关版权
// +----------------------------------------------------------------------
// | Author: fudaoji <fdj@kuryun.cn>
// +----------------------------------------------------------------------

/**
 * Created by PhpStorm.
 * Script Name: Material.php
 * Create: 2020/5/25 下午9:28
 * Description: 素材管理
 * @link https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Adding_Permanent_Assets.html  (微信素材文档说明)
 * Author: fudaoji<fdj@kuryun.cn>
 */

namespace app\mp\controller;

use app\common\model\MediaImage;
use app\common\model\MediaMusic;
use app\common\model\MediaNews;
use app\common\model\MediaText;
use app\common\model\MediaVideo;
use app\common\model\MediaVoice;
use app\common\model\Upload;
use ky\ErrorCode;
use ky\Helper;
use ky\MiniPlatform\ErrorMsg;
use think\Db;
use think\facade\Log;

class Material extends Base
{
    /**
     * @var \think\Model
     */
    private $uploadM;
    /**
     * @var MediaNews
     */
    private $newsM;
    /**
     * @var MediaImage
     */
    private $imageM;
    /**
     * @var MediaText
     */
    private $textM;
    /**
     * @var MediaVoice
     */
    private $voiceM;
    /**
     * @var MediaVideo
     */
    private $videoM;
    /**
     * @var MediaMusic
     */
    private $musicM;
    /**
     * @var \app\common\model\Addons
     */
    private $addonsM;
    /**
     * @var \app\common\model\mpAddon
     */
    private $mpAddonM;
    private $types = [
        'text','image', 'video', 'voice', 'music', 'news', 'addon'
    ];
    protected $needMpId  = false;
    public function initialize()
    {
        parent::initialize(); // TODO: Change the autogenerated stub
        $this->uploadM = new Upload();
        $this->newsM = new MediaNews();
        $this->imageM = new MediaImage();
        $this->textM = new MediaText();
        $this->voiceM = new MediaVoice();
        $this->videoM = new MediaVideo();
        $this->musicM = new MediaMusic();
        $this->addonsM = model('addons');
        $this->mpAddonM = model('mpAddon');
        $this->assign('config', config('system.upload'));
        set_time_limit(0);
    }

    /**
     * 获取图文详情
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function getNewsDetail(){
        $id = input('id', 0, 'intval');
        $media = $this->newsM->getOne(['uid' => $this->adminId, 'id' => $id]);
        if($media){
            $media['children'] = $this->newsM->getAll([
                'where' => ['uid' => $this->adminId, 'pid' => $media['id']],
                'field' => 'id,cover_url,title',
                'order' => ['index' => 'asc'],
                'refresh' => true
            ]);
        }
        if(request()->isPost()){
            return json(['code' => 1, 'msg' => 'success', 'data' => ['media' => $media]]);
        }
        return $media;
    }

    /**
     * 图文新增编辑
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function newsAdd(){
        if(request()->isPost()){
            $news_list = input('post.news_list');
            if(count($news_list) < 1){
                $this->error('请至少填写一条图文', '', ['token' => request()->token()]);
            }
            $pid = 0;
            $list = [];
            Db::startTrans();
            try {
                foreach ($news_list as $key => $item){
                    unset($item['selected'], $item['top']);
                    $item['uid'] = $this->adminId;
                    $valid = $this->validate($item, 'MediaNews.' . ($item['type'] == MediaNews::TYPE_LINK ? 'link' : 'wx'));
                    if($valid !== true){
                        return json(['code' => 0, 'msg' => $valid, 'data' => ['token' => request()->token()]]);
                    }

                    $item['mpid'] = $this->mpId;
                    if($item['id']){ //编辑
                        $res = $this->newsM->updateOne($item);
                        if($item['type'] == MediaNews::TYPE_WX) {
                            $upload_res = $this->mpApp->material->updateArticle($news_list[0]['media_id'], $item, $key);
                            if ($upload_res['errcode'] != 0) {
                                return json(['code' => 0, 'msg' => ErrorMsg::getErrorMsg($upload_res['errcode']), 'data' => ['token' => request()->token()]]);
                            }
                        }
                    }else{ //新增
                        $item['pid'] = $pid;
                        $item['index'] = $key;
                        $res = $this->newsM->addOne($item);
                    }
                    array_push($list, $res);
                    $key === 0 && $pid = $res['id'];
                }
                $head = $list[0];
                if($head['type'] == MediaNews::TYPE_WX){
                    if(! $news_list[0]['id']){ //新增微信图文时同步到微信
                        $upload_res = $this->mpApp->material->uploadArticle($news_list);
                        if(!empty($upload_res['media_id'])){
                            $list[0] = $this->newsM->updateOne([
                                'uid' => $head['uid'],
                                'id' => $head['id'],
                                'media_id' => $upload_res['media_id']
                            ]);
                        }else{
                            return json(['code' => 0, 'msg' => ErrorMsg::getErrorMsg($upload_res['errcode']), 'data' => ['token' => request()->token()]]);
                        }
                    }
                    //拉取素材，保存url
                    $download_res = $this->mpApp->material->get($list[0]['media_id']);
                    if(empty($download_res['news_item'])){
                        return json(['code' => 0, 'msg' => ErrorMsg::getErrorMsg($download_res['errcode']), 'data' => ['token' => request()->token()]]);
                    }else{
                        foreach ($download_res['news_item'] as $k => $v){
                            $this->newsM->updateOne([
                                'uid' => $head['uid'],
                                'id' => $list[$k]['id'],
                                'url' => $v['url']
                            ]);
                        }
                    }
                }
                //refresh
                $this->newsM->getOneByMap(['id' => $head['id'], 'uid' => $head['uid']], true, 1);
                Db::commit();
            }catch (\Exception $e){
                $res = false;
                Log::error($e->getMessage());
                Db::rollback();
            }

            if($res){
                $this->success('操作成功', url('index', ['type' => 'news', 'from' => ($head['type'] == MediaNews::TYPE_LINK ? 'local' : 'mp')]));
            }else{
                $this->error('系统繁忙，请稍后再试', '', ['token' => request()->token()]);
            }
        }
        $type = input('type', MediaNews::TYPE_WX);
        $list = [];
        if($id = input('id', 0)){
            $list = $this->newsM->getAll([
                'where' => ['id|pid' => $id, 'uid' => $this->adminId, 'mpid' => $this->mpId],
                'field' => 'id,title,thumb_media_id,cover_url,author,show_cover_pic,digest,content,content_source_url, media_id,pid, type',
                'refresh' => true,
                'order' => ['index' => 'asc'],
            ]);
            foreach ($list as $k => $v){
                $type = $v['type'];
                $v['selected'] = $k == 0 ? 1 : 0;
                $list[$k] = $v;
            }
        }
        $this->assign['type'] = $type;
        $this->assign['list'] = $list;
        return $this->show();
    }

    /**
     * 素材上传
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function uploadPost(){
        if(request()->isPost()) {
            $post_data = input('');
            $res = $this->uploadM->upload($_FILES, Upload::config($post_data['type']), ['uid' => $this->adminId]);

            if($res['code']){
                foreach ($res['data'] as $item){
                    $insert_data = [
                        'uid' => $item['uid'],
                        'mpid' => $this->mpId,
                        'title' => $item['original_name'],
                        'url' => $item['url'],
                        'size' => $item['size'],
                        'ext' => $item['ext'],
                        'location' => $item['location']
                    ];
                    $data = model('media_' . $post_data['type'])->addOne($insert_data);
                    if($post_data['from'] == 'mp'){
                        $this->uploadMedia2Wx($post_data['type'], $data['id']);
                    }
                }
                $this->success('上传成功');
            }else{
                $this->error($res['msg']);
            }
        }
    }

    /**
     * 上传素材至微信
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function materialSyncPost(){
        if(request()->isPost()){
            $post_data = input('post.');
            $media = model('media_'.$post_data['type'])->getOne(['id' => $post_data['id'], 'uid' => $this->adminId, 'mpid' => $this->mpId]);
            if(empty($media)){
                $this->error('非法操作');
            }
            $this->uploadMedia2Wx($post_data['type'], $post_data['id']);
            $this->success('上传成功');
        }
    }

    /**
     * 删除素材
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function materialDelPost(){
        $post_data = input();
        $ids = $post_data['ids'];
        $model = model('media_'.$post_data['type']);
        Db::startTrans();
        try {
            foreach ($ids as $id){
                $data = $model->getOne(['uid' => $this->adminId, 'id' => $id], 1);
                if($model->delOne(['uid' => $this->adminId, 'id' => $id])){
                    !empty($data['location']) && strtolower($data['location']) == 'local' && @unlink($data['path']); //删除本地文件
                    !empty($data['media_id']) && $this->mpApp->material->delete($data['media_id']); //删除永久素材
                }
                if($post_data['type'] === 'news'){ //删除子条目
                    $children = $model->getAll([
                        'where' => ['uid' => $this->adminId, 'pid' => $data['id']],
                        'refresh' => 1
                    ]);
                    foreach ($children as $c){
                        $model->delOne(['uid' => $c['uid'], 'id' => $c['id']]);
                    }
                }
                //refresh
                $model->getOneByMap(['id' => $data['id'], 'uid' => $data['uid']], true, 1);
            }
            $res = true;
            Db::commit();
        }catch (\Exception $e){
            Log::error($e->getMessage());
            Db::rollback();
            $res = false;
        }
        if($res === false){
            $this->error('系统错误，请刷新重试');
        }
        $this->success('删除成功');
    }

    /**
     * 素材列表
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function index(){
        $types = [
            'image' => '图片',
            'news' => '图文',
            'voice' => '音频',
            'video' => '视频'
        ];
        $froms = [
            'local' => '本地',
            'mp' => '微信',
        ];
        $from = input('from', 'local');
        $type = input('type', 'image');
        $search_key = input('search_key', '');
        $where = ['uid' => $this->adminId, 'media_id' => '', 'mpid' => $this->mpId];
        $from == 'mp' && $where['media_id'] = ['neq', ''];
        $search_key && $where['title'] = ['like', '%'.$search_key.'%'];
        $type == 'news' && $where['pid'] = 0;
        $data_list = model('media_' . $type)->page(12, $where, ['id' => 'desc'], true, 1);
        $pager = $data_list->appends(['from' => $from, 'type' => $type, 'search_key' => $search_key])->render();
        if($type == 'news'){
            foreach ($data_list as $k => $v){
                $where['pid'] = $v['id'];
                unset($where['media_id']);
                $v['child'] = model('media_' . $type)->getAll([
                    'where' => $where,
                    'field' => 'cover_url,title',
                    'order' => ['index' => 'asc'],
                    'refresh' => true
                ]);
                $data_list[$k] = $v;
            }
        }
        $assign = [
            'data_list' => $data_list,
            'from' => $from,
            'froms' => $froms,
            'type' => $type,
            'types' => $types,
            'pager' => $pager
        ];
        return $this->show($assign);
    }

    /**
     * frame素材列表
     * @return mixed
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function handle(){
        $params = input();
        if(empty($params['type'])){
            $type = 'image';
        }else{
            if(in_array($params['type'], $this->types)){
                $type = $params['type'];
            }else{
                echo "type参数错误";exit;
            }
        }
        if(method_exists($this, $type)){
            return call_user_func([$this, $type]);
        }else{
            echo $type . "方法不存在";exit;
        }
    }

    /**
     * 音频
     * @return mixed
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function voice(){
        $from = input('from', 'local'); //本地或微信
        $field = input('field', ''); //目标input框
        $where = ['uid' => $this->adminId, 'media_id' => ''];
        $need_mp = input('needmp', 0);
        $need_mp  && $where['mpid'] = $this->mpId;
        if($from == 'mp'){
            $where['media_id'] = ['neq', ''];
        }
        $data_list = $this->voiceM->page(7, $where, ['id' => 'desc'], 'id,title,url', 1);
        $pager = $data_list->render();
        $assign = ['data_list' => $data_list, 'pager' => $pager, 'field' => $field, 'from' => $from];
        return $this->show($assign, __FUNCTION__);
    }

    /**
     * 文本
     * @return mixed
     * @throws \think\Exception
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function text(){
        if(request()->isPost()){
            $post_data = input('post.');
            $post_data['uid'] = $this->adminId;
            if($res = $this->textM->addOne($post_data)){
                $this->success('保存成功');
            }
            $this->error('保存失败，请刷新重试');
        }
        $field = input('field', ''); //目标input框
        $where = ['uid' => $this->adminId];
        $data_list = $this->textM->page(7, $where, ['id' => 'desc'], 'id,content', 1);
        $pager = $data_list->render();
        $assign = ['data_list' => $data_list, 'pager' => $pager, 'field' => $field];
        return $this->show($assign, __FUNCTION__);
    }

    /**
     * 删除文本素材
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function textDelPost(){
        $post_data = input();
        $ids = $post_data['ids'];
        foreach ($ids as $id){
            $this->textM->delOne(['uid' => $this->adminId, 'id' => $id]);
        }
        $this->success('操作成功');
    }

    /**
     * 图文
     * @return mixed
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function news(){
        $from = input('from', 'local'); //本地或微信
        $field = input('field', ''); //目标input框
        $where = ['uid' => $this->adminId, 'pid' => 0, 'mpid' => $this->mpId];

        $data_list = $this->newsM->page(12, $where, ['id' => 'desc'], 'id,cover_url,title,digest', 1);
        $pager = $data_list->appends(['from' => $from])->render();
        foreach ($data_list as $k => $v){
            $where['pid'] = $v['id'];
            unset($where['media_id']);
            $v['child'] = $this->newsM->getAll([
                'where' => $where,
                'field' => 'cover_url,title',
                'order' => ['index' => 'asc'],
                'refresh' => true
            ]);
            $data_list[$k] = $v;
        }
        $assign = ['data_list' => $data_list, 'pager' => $pager, 'from' => $from, 'field' => $field];
        return $this->show($assign, __FUNCTION__);
    }

    /**
     * 图片
     * @return mixed
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function image(){
        $from = input('from', 'local'); //本地或微信
        $field = input('field', ''); //目标input框
        $where = ['uid' => $this->adminId, 'media_id' => ''];
        $need_mp = input('needmp', 0);
        $need_mp  && $where['mpid'] = $this->mpId;
        if($from == 'mp'){
            $where['media_id'] = ['neq', ''];
        }
        $data_list = $this->imageM->page(12, $where, ['id' => 'desc'], 'id,url,title,media_id', 1);
        $pager = $data_list->appends(['from' => $from])->render();
        $assign = ['data_list' => $data_list, 'pager' => $pager, 'from' => $from,
            'field' => $field, 'only_mp' => input('onlymp', 0, 'intval')
        ];
        return $this->show($assign, __FUNCTION__);
    }

    /**
     * 音乐
     * @return mixed
     * @throws \think\Exception
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function music(){
        if(request()->isPost()){
            $post_data = input('post.');
            $post_data['uid'] = $this->adminId;
            $post_data['mpid'] = $this->mpId;
            if($res = $this->musicM->addOne($post_data)){
                $this->success('保存成功');
            }
            $this->error('保存失败，请刷新重试');
        }
        $from = input('from', 'local'); //本地或微信
        $field = input('field', ''); //目标input框
        $where = ['uid' => $this->adminId];
        $need_mp = input('needmp', 0);
        $need_mp  && $where['mpid'] = $this->mpId;

        $data_list = $this->musicM->page(7, $where, ['id' => 'desc'], 'id,url,title', 1);
        $pager = $data_list->appends(['from' => $from])->render();
        $assign = ['data_list' => $data_list, 'pager' => $pager, 'field' => $field];
        return $this->show($assign, __FUNCTION__);
    }

    /**
     * 视频
     * @return mixed
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function video(){
        $from = input('from', 'local'); //本地或微信
        $field = input('field', ''); //目标input框
        $where = ['uid' => $this->adminId, 'media_id' => ''];
        $need_mp = input('needmp', 0);
        $need_mp  && $where['mpid'] = $this->mpId;
        if($from == 'mp'){
            $where['media_id'] = ['neq', ''];
        }
        $data_list = $this->videoM->page(12, $where, ['id' => 'desc'], 'id,url,title', 1);
        $pager = $data_list->appends(['from' => $from])->render();
        $assign = ['data_list' => $data_list, 'pager' => $pager, 'from' => $from, 'field' => $field];
        return $this->show($assign, __FUNCTION__);
    }

    /**
     * 应用插件
     * @return mixed
     * @throws \think\exception\DbException
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function addon(){
        $field = input('field', ''); //目标input框
        $where = ['mpid' => $this->mpId, 'a.status' => 1];
        $data_list = $this->mpAddonM->pageJoin([
            'alias' => 'ma',
            'join' => [['addons a', 'a.addon=ma.addon']],
            'page_size' => 7,
            'where' => $where,
            'field' => ['a.id','a.name', 'a.desc', 'a.logo'],
            'order' => ['ma.id' => 'desc'],
            'refresh' => 1
        ]);
        $pager = $data_list->render();
        $assign = ['data_list' => $data_list, 'pager' => $pager, 'field' => $field];
        return $this->show($assign, __FUNCTION__);
    }
}